
박싱과 언박싱
Boxing : 값타입을 참조타입으로 변환하는 기법 UnBoxing : 참조타입을 값타입으로 변환하는 기법
1. 값타입
스택 : 저장
- 선언되는 즉시 메모리를 할당하게 된다.
- 따라서 생성과 동시에 값을 할당할 수도 있다. int a = 3;
2. 참조타입
힙 : 저장 스택 : (C의 포인터처럼) 저장된 것의 주소값만 가짐
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// 유리병(값타입) -> 유리병 그대로 배달 X -> 택배차 : 거부 (우린 택배박스만 받는다)
// 유리병 -> 택배포장 -> 택배차
// 값타입 -> 참조타입으로 포장(박싱) -> 참조타입만 받는 매개변수에 전달
public class BoxingTest
{
public static void Main(string[] args)
{
int p = 123; // 값타입
Object o = p; // (자동으로 박싱) 박싱후 o에 들어가는 상황
int j = (int)o; // 언박싱 : 내가 명시적으로 캐스팅을 해줘야 한다
Console.WriteLine(p);
Console.WriteLine(o);
Console.WriteLine(j);
}
}
비유하자면 우리집이라는 객체를 메모리에할당할 경우,
우리집은 힙 영역에 저장되고 스택 영역에서는 우리집을 가르키는 주소
* 참조타입은 새로운 값을 할당하기 위해서는 new를 통해 선은을 해줘야 한다.
class 우리집
{
public void 안방()
{
}
}
public class BoxingTest
{
public static void Main(string[] args)
{
int a = 10; // 값타입
우리집 b201호 = new 우리집(); // 참조타입
b201호.안방();
}
}
쿠팡이라는 온라인마켓 int 모양의 상품, double 모양의 상품, String 모양의 상품, 객체 모양의 상품 (별의별 물건 다 팜) 할때마다 int 전용 택배차 따로, double 전용 택배차를 일일히 다 만들면 비효율적이다 포장 -> 모두 같은 택배차에 실어 나르자
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public class 쿠팡맨
{
public void 배송출발(Object o)
{
Console.WriteLine("배달하는 물건 : "+ o );
}
}
public class BoxingTest
{
public static void Main(string[] args)
{
쿠팡맨 man = new 쿠팡맨();
int 주문상품1 = 123; // 값타입 (그냥 택배차에 못 실음)
double 주문상품2 = 3.14; // 값타입
String 주문상품3 = "이미포장됨"; // 참조타입
man.배송출발(주문상품1); // 값 타입이 자동으로 참조타입으로 박싱된 후 전달됨 (택배포장이 된 후)
man.배송출발(주문상품2); // 값 타입이 자동으로 참조타입으로 박싱된 후 전달됨 (택배포장이 된 후)
man.배송출발(주문상품3);
man.배송출발(man); // 쿠팡맨은 포장 안하고 그냥 택배차에 올라탐 (참조타입은 그냥 들어감)
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections; // ArrayList 쓰려고 추가함
public class BoxingTest
{
public static void Main(string[] args)
{
ArrayList list = new ArrayList();
// 1. 박싱되는 예시
list.Add(new BoxingTest()); // list[0] 공간 : 참조타입인 객체가 전달
list.Add("안녕하세요"); // list[1] 공간 : 참조타입인 문자열이 전달 (heap 영역에 저장 근데 문자열은 특이하게도 new 키워드를 안써도 된다)
list.Add(3.14); // list[2] 공간 : 값타입인 실수가 (자동으로 박싱이 된 후) 전달
list.Add(123); // list[3] 공간 : 값타입인 정수가 (자동으로 박싱이 된 후) 전달
// 2. 정상 삽입됐나 확인
Object o1 = list[2]; // list.Add(3.14); 이게 정상적으로 삽입됐나?
Object o2 = list[3]; // list.Add(123); 이게 정상적으로 삽입됐나?
Console.WriteLine(o1);
Console.WriteLine(o2);
// 3. 전체 출력
PrintValues(list);
}
// 출력 함수
public static void PrintValues(IEnumerable 리스트)
{
foreach (Object obj in 리스트)
{
Console.WriteLine("{0}", obj);
}
}
}